/*******************************************************************/
/*    Copyright (c) 2008-2010 by Transoft Corp.                    */
/*    All rights reserved.                                         */
/*******************************************************************/

// System
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef _MSC_VER
#include <locale.h>
#include <wtypes.h>
#include <winnt.h>

//nsb : Windows is defining 'GetMessage' as 'GetMessageA' and we get into trouble
#undef GetMessage
#endif // _MSC_VER

#include "kernapi.hxx"
#include "cstrapi.hxx"
#include "lists.hxx"

#include "fileinfo.hxx"

#include "SPAIDocument.h"
#include "SPAIAcisDocument.h"
#include "SPAIConverter.h"
#include "SPAIFile.h"
#include "SPAIResult.h"
#include "SPAIOptions.h"
#include "SPAIOptionName.h"
#include "SPAIValue.h"
#include "SPAIDocumentAssemblyInfo.h"
#include "SPAISystemInitGuard.h"

//#include "V5Works_lic/V5WorksProtection.h"

//-----------------------------------------------------------------------------
//Added for multibyte
//-----------------------------------------------------------------------------
#ifdef _MSC_VER

const char* setOSlocale()
{	
	const char *oldLocal = setlocale( LC_ALL,  NULL );

	LCID Locale = GetThreadLocale();

	TCHAR cpname[30];
	int nbytes = 0;

	GetLocaleInfo (Locale, LOCALE_SENGLANGUAGE, cpname, 30);

	TCHAR cpchain1[30];

	nbytes = GetLocaleInfo (Locale, LOCALE_SENGCOUNTRY   , cpchain1, 30);

	TCHAR cpchain[6];

	nbytes = GetLocaleInfo (Locale, LOCALE_IDEFAULTANSICODEPAGE, cpchain, 6);

	TCHAR NewLocal[1024];

	sprintf( NewLocal, "%s_%s.%s",cpname,cpchain1,cpchain);

	setlocale( LC_ALL,  NewLocal );

	return oldLocal;
}

#endif // MSC_VER

void printHelp()
{
	printf("Usage : Simple -i file [-iformat format] -o file \n");
	printf("Options :\n");
	printf("-i        : input file\n");
	printf("-iformat  : input format\n");
	printf("-o        : output file\n");
	printf("-options  : options file\n");
	printf("-log      : log file\n");
}

char pszInputFile[256]="";
char pszOutputFile[256]="";
char pszInputFormat[256]="";
char pszInputInfoFile[256]="";
char pszOptionsFile[256]="";
char pszLogFile[256]="";

bool bParaSolid = false;

int getArgs(int argc, char *argv[])
{
	int err=0;

	if(argc <= 1)
	{
		printHelp();
		err = 1;
		return 1;
	}

	int i=1;
	while (i<argc)
	{
		if (strcmp("-i", argv[i])==0)
		{
			if (++i<argc)
			{
				strncpy(pszInputFile, argv[i], 256);
			}
			else
			{
				printHelp();
				err=1;
			}
		}
		else if (strcmp("-o", argv[i])==0)
		{
			if (++i<argc)
			{
				strncpy(pszOutputFile, argv[i], 256);
			}
			else
			{
				printHelp();
				err=1;
			}
		}
		else if (strcmp("-iformat", argv[i])==0)
		{
			if (++i<argc)
			{
				strncpy(pszInputFormat, argv[i], 256);
			}
			else
			{
				printHelp();
				err=1;
			}
		}
		else if (strcmp("-log", argv[i])==0)
		{
			if (++i<argc)
			{
				strncpy(pszLogFile, argv[i], 256);
			}
			else
			{
				printHelp();
				err=1;
			}
		}
		else if (strcmp("-options", argv[i])==0)
		{
			if (++i<argc)
			{
				strncpy(pszOptionsFile, argv[i], 256);
			}
			else
			{
				printHelp();
				err=1;
			}
		}

		++i;
	}

	if( (0 == strcmp(pszInputFile, "") ) || (0 == strcmp(pszOutputFile, "") ) )
	{
		printHelp();
		err = 1;
	}

	return err;
}

bool getFileExtension( const char *szFName, char *szExt )
{
	bool bResult = false;

	const char *szTemp = strrchr(szFName, '.');

	while (szTemp != NULL)
	{
		const char *szExtension = szTemp + 1;

		//add by wumin 2006.08.31 for proe asm and prt
		if ((atoi(szExtension)))
		{
//			memset(szTemp,'\0',1);
			szExtension = strrchr(szFName, '.') + 1;
		}

		if (_stricmp(szExtension, "iges") == 0 ||
			_stricmp(szExtension, "ige") == 0 ||
			_stricmp(szExtension, "stp") == 0 ||
			_stricmp(szExtension, "step") == 0 ||
			_stricmp(szExtension, "catpart") == 0 ||
			_stricmp(szExtension, "catproduct") == 0 ||
			_stricmp(szExtension, "asm") == 0 ||
			_stricmp(szExtension, "prt") == 0 ||
			_stricmp(szExtension, "sldprt") == 0 ||
			_stricmp(szExtension, "sldasm") == 0 ||
			_stricmp(szExtension, "model") == 0 ||
			_stricmp(szExtension, "sat") == 0 ||
			_stricmp(szExtension, "xml") == 0 )
		{
			sprintf( szExt, "%s", szExtension);
			bResult = true;
			break;
		}
	}
	return bResult;
}

void unlock_spatial_products_5489();

int main(int argc, char *argv[])
{
	int err = 0;

	// V5Works license check
	//if (CheckV5WorksLicense() == false)
	//{
	//	return err;
	//}
	SPAISystemInitGuard initGuard;

#ifdef _MSC_VER
	setOSlocale();
	unlock_spatial_products_5489();
#endif

	if ( ( err = getArgs(argc, argv) ) !=0 )
		return err;

	SPAIResult result=SPAI_S_OK;

	SPAIDocument src(pszInputFile);
	if (strlen(pszInputFormat)>0)
		src.SetType(pszInputFormat);

	char pszFileExtension[20];
	getFileExtension(pszInputFile,pszFileExtension);

	if ( _stricmp(pszFileExtension,"CATProduct") == 0 ) // CATIA Product
	{
		// Export xml file
 		SPAIDocument src(pszInputFile);
 		const char *assemblyInfoFile = pszOutputFile;
 		SPAIDocumentAssemblyInfo srcInfo(src);
 		SPAIFile inputAssemblyInfoFile(assemblyInfoFile);
 		SPAIResult iResult = srcInfo.SaveAs(inputAssemblyInfoFile);
		//SPAIConverter converter; 
		//SPAIOptions options;
		//options.Add("EBOM.ImportParts",false);
		//result&=converter.SetOptions(options); 
		//result&=converter.Convert(src, dst);	
	}
	else if ( _stricmp(pszFileExtension,"CATPart") == 0) // CATIA Part
	{
		/*	bool bParaSolid = false;
		if( strstr(pszOutputFile,".x_t") != NULL || strstr(pszInputFile,".x_t") != NULL)
		{
		bParaSolid = true;
		}

		if (bParaSolid)
		{
		SPAIDocument dst(pszOutputFile); 

		SPAIOptions options;

		if (strlen(pszOptionsFile)>0)
		{
		SPAIFile optionsFile(pszOptionsFile);
		SPAIResult optResult = options.Load(optionsFile);
		if(optResult!= SPAX_S_OK)
		{
		printf( "Option file not loaded correctly.Check the syntax\n");
		}
		}

		options.Add(SPAIOptionName("SaveVersion"),160);  // For ParaSolid

		SPAIFile logFile(pszLogFile);

		SPAIConverter converter; 
		result&=converter.SetOptions(options); 
		result&=converter.StartLog(logFile); 
		result&=converter.Convert(src, dst); 
		result&=converter.StopLog(logFile); 
		}
		else //
		{
			SPAIAcisDocument dst; 

			SPAIOptions options;

			if (strlen(pszOptionsFile)>0)
			{
				SPAIFile optionsFile(pszOptionsFile);
				SPAIResult optResult = options.Load(optionsFile);
				if(optResult!= SPAX_S_OK)
				{
					printf( "Option file not loaded correctly.Check the syntax\n");
				}
			}

			SPAIFile logFile(pszLogFile);

			SPAIConverter converter; 
			result&=converter.SetOptions(options); 
			result&=converter.StartLog(logFile); 
			result&=converter.Convert(src, dst); 
			result&=converter.StopLog(logFile); 


			ENTITY_LIST* pAcisEntities=NULL; 

			dst.GetEntities(pAcisEntities); 
			dst.DetachEntities(); 

			FileInfo info;
			char* id_string = "InterOp";
			info.set_product_id(id_string);
			info.set_units(1.0);
			outcome rc =  api_set_file_info((FileId | FileUnits), info); 
			info.reset();

			//Save to version 14 which can be recognized by SolidWorks 2006+
			api_save_version(14,0);

			if( pAcisEntities != NULL )
			{
				FILE* pAcisFile=fopen(pszOutputFile, "w"); 
				if ( pAcisFile != NULL ) 
				{ 
					api_save_entity_list(pAcisFile, true, *pAcisEntities); 
					fclose(pAcisFile);
				}
			}
SPAIDocument dst(pszOutputFile); 

SPAIOptions options;

if (strlen(pszOptionsFile)>0)
{
SPAIFile optionsFile(pszOptionsFile);
SPAIResult optResult = options.Load(optionsFile);
if(optResult!= SPAX_S_OK)
{
printf( "Option file not loaded correctly.Check the syntax\n");
}
}
		// 9/2/2008 mwu : save to ACIS VERSION 14 
options.Add(SPAIOptionName("SaveMajorVersion"),14); // For ACIS, undocumented option, solidworks 2006 can accept ACIS R14,and SolidWorks2008 can accept ACIS R17.

SPAIFile logFile(pszLogFile);

SPAIConverter converter; 
result&=converter.SetOptions(options); 
result&=converter.StartLog(logFile); 
result&=converter.Convert(src, dst); 
result&=converter.StopLog(logFile); 

}
*/

// 		SPAIDocument dst(pszOutputFile); 
// 
// 		SPAIOptions options;
// 
// 		if (strlen(pszOptionsFile)>0)
// 		{
// 			SPAIFile optionsFile(pszOptionsFile);
// 			SPAIResult optResult = options.Load(optionsFile);
// 			if(optResult!= SPAX_S_OK)
// 			{
// 				printf( "Option file not loaded correctly.Check the syntax\n");
// 			}
// 		}
// 
// // 		options.Add(SPAIOptionName("SaveVersion"),160);  // For ParaSolid
// // 		options.Add(SPAIOptionName("SaveMajorVersion"),14); // For ACIS, undocumented option, solidworks2006 can accept ACIS R14,and SolidWorks2008 can accept ACIS R17.
// #ifdef GENERIC
// 		options.Add(SPAIOptionName("SaveVersion"),160);  // For ParaSolid
// #else
// 		options.Add(SPAIOptionName("SaveMajorVersion"),14); // Not supported from R20
// //		options.Add(SPAIOptionName("SaveVersion"),1800); // Only support 1800 and 1900 in R20
// #endif
// 
// 		options.Add(SPAIOptionName("EnableSurfaceSimplification"),TRUE);  // Common
// 		options.Add(SPAIOptionName("EnableCurveSimplification"),TRUE);  // Common
// 
// 		SPAIFile logFile(pszLogFile);
// 
// 		SPAIConverter converter; 
// 		result&=converter.SetOptions(options); 
// 		result&=converter.StartLog(logFile); 
// 		result&=converter.Convert(src, dst); 
// 		result&=converter.StopLog(logFile); 

		SPAIOptions options;

		if (strlen(pszOptionsFile)>0)
		{
			SPAIFile optionsFile(pszOptionsFile);
			SPAIResult optResult = options.Load(optionsFile);
			if(optResult!= SPAI_S_OK)
			{
				printf( "Option file not loaded correctly.Check the syntax\n");
			}
		}

		options.Add("EnableSurfaceSimplification",TRUE);  // Common
		options.Add("EnableCurveSimplification",TRUE);  // Common

		SPAIFile logFile(pszLogFile);

		SPAIAcisDocument dst;
		SPAIConverter converter; 
		result&=converter.SetOptions(options); 
		result&=converter.StartLog(logFile); 
		result&=converter.Convert(src, dst);
		result&=converter.StopLog(logFile); 

		outcome rc = api_start_modeller(0);
		rc = api_initialize_kernel();
		{
			ENTITY_LIST* pAcisEntities = NULL;
			dst.GetEntities(pAcisEntities);

			dst.DetachEntities();

			//save entity
			// Write out the "SAT" data file
			FileInfo fileinfo;
			fileinfo.set_units( 1.0 );
			fileinfo.set_product_id( "V5Works" );
			rc = api_set_file_info( ( FileId | FileUnits ) , fileinfo );

			api_save_version(14,0);// For ACIS, undocumented option, solidworks2006 can accept ACIS R14,and SolidWorks2008 can accept ACIS R17.
			//			api_save_version(19,0);// For ACIS, undocumented option, solidworks2010 can accept ACIS R19,and SolidWorks2008 can accept ACIS R17.
			//			api_save_version(22,0);// For ACIS, undocumented option, solidworks2013 can accept ACIS R22

			FILE* save_file = fopen( pszOutputFile , "w" );
			ENTITY* ent = pAcisEntities->operator [](0);
			rc = api_save_entity_list( save_file , TRUE , *pAcisEntities );

			if (save_file != NULL)
			{
				fclose( save_file );
			}
			pAcisEntities->clear();
			if (pAcisEntities != NULL )
			{
				ACIS_DELETE pAcisEntities;
				pAcisEntities = NULL;
			}
		}
		rc = api_terminate_kernel();
		rc = api_stop_modeller();
	}
	else if ( _stricmp(pszFileExtension,"sat") == 0) // SAT Part
	{
		SPAIOptions options;

		if (strlen(pszOptionsFile)>0)
		{
			SPAIFile optionsFile(pszOptionsFile);
			SPAIResult optResult = options.Load(optionsFile);
			if(optResult!= SPAI_S_OK)
			{
				printf( "Option file not loaded correctly.Check the syntax\n");
			}
		}

		options.Add("EnableSurfaceSimplification",TRUE);  // Common
		options.Add("EnableCurveSimplification",TRUE);  // Common
//		options.Add("SaveVersion","CATIAV5R17");

		SPAIFile logFile(pszLogFile);
		SPAIFile dst(pszOutputFile);

		SPAIConverter converter; 
		result&=converter.SetOptions(options); 

		result&=converter.StartLog(logFile); 
		result&=converter.Convert(src, dst);
		result&=converter.StopLog(logFile); 

	}
	else if ( _stricmp(pszFileExtension,"xml") == 0) // XML
	{

	}

	return result;

}

